package org.idea.qiyu.alarm.starter.handler;

import com.alibaba.fastjson.JSON;
import org.idea.qiyu.alarm.starter.event.WebExceptionErrorEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.apache.commons.lang3.exception.ExceptionUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author linhao
 * @Date created in 6:33 下午 2021/7/13
 */
@Order(Ordered.LOWEST_PRECEDENCE - 1)
@Component("webExceptionHandler")
@ControllerAdvice
public class WebExceptionHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebExceptionHandler.class);

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler({Exception.class})
    public void unhandledServerError(HttpServletRequest req, HttpServletResponse response, Throwable e) throws IOException {
        DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String currentTime = dateTimeFormatter2.format(LocalDateTime.now());
        String errorContent = "\n[服务器异常] 服务器ip: " + getIp() + "  url: " + req.getRequestURI() + ",  time: "+ currentTime +"\n" +
                "exception: " + ExceptionUtils.getStackTrace(e);
        LOGGER.error(errorContent);
        applicationEventPublisher.publishEvent(new WebExceptionErrorEvent(errorContent));
        this.buildCommonErrorResponse(response);
    }


    private static String getIp() {
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            LOGGER.warn("获取本机IP失败", e);
        }
        return "机器IP未知";
    }

    /**
     * 构建各个服务中的通用异常响应类
     *
     * @param response
     * @return
     */
    private void buildCommonErrorResponse(HttpServletResponse response) throws IOException {
        Map<String, Object> results = new HashMap(3);
        results.put("code", HttpStatus.INTERNAL_SERVER_ERROR.value());
        results.put("msg", "服务器开小差了");
        results.put("data", "null");
        response.setContentType("application/json" + ";charset=" + "UTF-8");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0L);
        response.getWriter().write(JSON.toJSONString(results));
    }
}
